﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DDD;
using Xunit;

using Vector3 = DDD.Vector3<float>;
using Vector4 = DDD.Vector4<float>;


namespace DokiDokiTest {
    public class TestVector4 {

        [Fact]
        public void Test_New1 () {
            var v = new Vector4 ();

            Assert.Equal (4, v.ComponentCount);
            Assert.Equal (0, v.X);
            Assert.Equal (0, v.Y);
            Assert.Equal (0, v.Z);
            Assert.Equal (0, v.W);
            Assert.Equal (0, v[0]);
            Assert.Equal (0, v[1]);
            Assert.Equal (0, v[2]);
            Assert.Equal (0, v[3]);
        }

        [Fact]
        public void Test_New2 () {
            var v = new Vector4 (1, 2, 3, 4);

            Assert.Equal (4, v.ComponentCount);
            Assert.Equal (1, v.X);
            Assert.Equal (2, v.Y);
            Assert.Equal (3, v.Z);
            Assert.Equal (4, v.W);
            Assert.Equal (1, v[0]);
            Assert.Equal (2, v[1]);
            Assert.Equal (3, v[2]);
            Assert.Equal (4, v[3]);
        }

        [Fact]
        public void Test_New3 () {
            var v = new Vector4 (new float[] { 1, 2, 3, 4 });
            var expected = new float[] { 1, 2, 3, 4 };

            Assert.Equal (expected, (float[])v);
        }

        [Fact]
        public void Test_New4 () {
            var v = new Vector4 (new Vector3(1,2,3), 4);

            Assert.Equal (1, v.X);
            Assert.Equal (2, v.Y);
            Assert.Equal (3, v.Z);
            Assert.Equal (4, v.W);
            Assert.Equal (1, v[0]);
            Assert.Equal (2, v[1]);
            Assert.Equal (3, v[2]);
            Assert.Equal (4, v[3]);
        }

        [Fact]
        public void Test_New5 () {
            Assert.Equal (new float[] { 0, 1, 0, 1 }, (float[])Vector4.Up);
            Assert.Equal (new float[] { 0, -1, 0, 1 }, (float[])Vector4.Down);
            Assert.Equal (new float[] { 1, 0, 0, 1 }, (float[])Vector4.Right);
            Assert.Equal (new float[] { -1, 0, 0, 1 }, (float[])Vector4.Left);
            Assert.Equal (new float[] { 0, 0, -1, 1 }, (float[])Vector4.Forward);
            Assert.Equal (new float[] { 0, 0, 1, 1 }, (float[])Vector4.Back);
            Assert.Equal (new float[] { 0, 0, 0, 1 }, (float[])Vector4.Zero);
        }



        [Fact]
        public void Test_Indexer () {
            var v = new Vector4 ();
            v[0] = 1;
            v[1] = 2;
            v[2] = 3;
            v[3] = 4;
            Assert.Equal (1, v[0]);
            Assert.Equal (2, v[1]);
            Assert.Equal (3, v[2]);
            Assert.Equal (4, v[3]);
        }

        [Fact]
        public void Test_Convertor () {
            var v = new Vector4 (1, 2, 3, 4);
            var expected = new float[] { 1, 2, 3, 4 };

            Assert.Equal (expected, (float[])v);
        }

        [Fact]
        public void Test_DevidedByW () {
            var v = new Vector4 (2, 4, 6, 2).DividedByW ();

            Assert.Equal (1, v.X);
            Assert.Equal (2, v.Y);
            Assert.Equal (3, v.Z);
        }


        [Fact]
        public void Test_Equals () {
            var v1 = new Vector4 (0, 0, 0, 1.00f);
            var v2 = new Vector4 (0, 0, 0, 1.02f);
            var tmp = GlobalSettings.Tolerance;

            GlobalSettings.Tolerance = 0.1f;

            Assert.True (v1 == v2);
            Assert.True (v1.Equals (v2));
            Assert.True (v1.Equals ((object)v2));
            Assert.False (v1 != v2);

            GlobalSettings.Tolerance = 0.01f;

            Assert.False (v1 == v2);
            Assert.False (v1.Equals (v2));
            Assert.False (v1.Equals ((object)v2));
            Assert.True (v1 != v2);

            GlobalSettings.Tolerance = tmp;
        }

    }
}
